package com.wdl.webserver.api;

import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;

import org.influxdb.InfluxDB;
import org.influxdb.InfluxDBFactory;
import org.influxdb.dto.Point;
import org.influxdb.dto.Point.Builder;
import org.influxdb.dto.Query;
import org.influxdb.dto.QueryResult;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * 时序数据库 InfluxDB 连接
 */
@Component
public class InfluxDBData {
	@Value("${influx.user}")
	private String user;// 用户名
	@Value("${influx.pwd}")
	private String pwd;// 密码
	@Value("${influx.url}")
	private String url;// 连接地址
	@Value("${influx.database}")
	private String database;// 数据库

	private volatile static InfluxDB influxDB;

	@PostConstruct
	private void influxDbBuild() {
		// 双重校验锁，安全可靠
		if (influxDB == null) {
			synchronized (InfluxDB.class) {
				if (influxDB == null) {
					influxDB = InfluxDBFactory.connect(url, user, pwd);
				}
			}
		}
	}  

	/**
	 * 设置数据保存策略 defalut 策略名 /database 数据库名/ 30d 数据保存时限30天/ 1 副本个数为1/ 结尾DEFAULT 表示
	 * 设为默认的策略
	 */
	public void createRetentionPolicy() {
		String command = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s DEFAULT",
				"defalut", database, "30d", 1);
		this.query(command);
	}

	/**
	 * 查询
	 * 
	 * @param command 查询语句
	 * @return
	 */
	public QueryResult query(String command) {
		return influxDB.query(new Query(command, database), TimeUnit.MILLISECONDS);
	}

	/**
	 * 插入
	 * 
	 * @param measurement 表
	 * @param tags        标签
	 * @param fields      字段
	 */
	public void insert(String measurement, Map<String, String> tags, Map<String, Object> fields) {
		Builder builder = Point.measurement(measurement);
		builder.tag(tags);
		builder.fields(fields);

		influxDB.write(database, "", builder.build());
	}

	/**
	 * 删除
	 * 
	 * @param command 删除语句
	 * @return 返回错误信息
	 */
	public String deleteMeasurementData(String command) {
		QueryResult result = influxDB.query(new Query(command, database));
		return result.getError();
	}

	/**
	 * 创建数据库
	 * 
	 * @param dbName
	 */
	public void createDB(String dbName) {
		influxDB.createDatabase(dbName);
	}

	/**
	 * 删除数据库
	 * 
	 * @param dbName
	 */
	public void deleteDB(String dbName) {
		influxDB.deleteDatabase(dbName);
	}

	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getDatabase() {
		return database;
	}

	public void setDatabase(String database) {
		this.database = database;
	}
}
